/*
 * @Description:
 * @Author: maxyang
 * @Date: 2022-08-09 11:17:39
 * @LastEditTime: 2022-08-09 22:02:49
 * @LastEditors: liutq
 * @Reference:
 */
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/smartwalle/alipay/v3"
	"github.com/smartwalle/xid"
)

var aliClient *alipay.Client

const (
	kAppId = "2016102000728006"
	// kPrivateKey   = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDb8E2wW9ap/YrUAR8dWBBFIxUifgoqZVQrOOjb1DlHCyRJr2TSA7sYu++dTJBsr94az/z8m0Cv+on4khlv4fnWZjOHCsA9SgVb+SnDWVO5DAeJqVTBekMtFZy6Wii/tpxBo4k/IH4juPbF78qlc/iDO9Fc86MdkgnAn44yAxgYneoiA/lJT0/tz8fJsR/Y+cYkSqv00e2s8VRvrpTPp6x3YnVzDlow5DH1oAuflGEGB2r5bZu7CSo+pbZndrTYH0tjqTxfP0dE/8GZv9RHHfKV68G+Agfmp1JBS18yPghJ6MS9d9chj0gSbtYZjozvFw23cId37vdEkNuC+slsipybAgMBAAECggEBAKMXoSSEFbzcjJQFeOMzqGz8RPHc8QDbPv0GKHbK+uZZtsEFVQf/SEBhLKBCZF6UU2kijoFrRx639JPlEwPKWI/KHa+oI0HPoAXB0FxR4ym3Z+eHL5iBZ0sJWb0+mjT/3wM1l9K974vh3uyMkoL6anA2bVw2NuD4qE60gqdHcBjfsI0ngvmOaoSFR3GS91wiw8ZQekj9dsytr+wM8JDGyn0sxUwuC+gQl3Mf/yUVvRTeOc52Ih+bzYMn8pBq/nVEHCBFXbYRu7WYj5/GLKtB+eDV9HZFT96J1G9igWGm17iv+vkqISAutEhv0aP/Dn8CZPziAC9ZS/19RcIjVtL6n+ECgYEA+o53c0983RtdJyfrJkd+KmSmFMXDH1h12LC0hFa0TUHOzrYH0JPBHKe2BfiqLEDOubSIDTNsJS20Bp2HHdpOJ1pRZS3QFTu04cbisWZWVlld/Ck7lRs29oTP06HUm3QdzncWde9fENnPUdlUeGX98loJJnaEDeSmuix7A9ME7mkCgYEA4LeMT9xAmz3TZTqQ918BzGU8urOViLCvi9W/9VL+tj4VLoY5SUNPOqoXZYzYeWJkc/hxCDGtJ3WSFv3mHSXmtb/yEY/wn8mH3jBd3boBid55MyimxId5/j0VW7C7uHX22rVP/qVqQLqI5YvgxNhnaqh+uvXXiQN9xFWZCpAV2mMCgYAjoa8LDvrK1uFgeCTQxMoEbVvRCG6/Pm1D651AVLQ/aGRosSpbVyfXU2JnZv2MXYsIjcvrVKzEfMNlTXGxpSIIJqf8o4879cm7cfU7FTqh/QOIoLSAd+ZRGIIVrqX1lYXHntfq3ae/VbpOAYIpvRdoJ7W1apVNBH9RapHz8UZ6QQKBgBSSuVXWZFPSJThvVDZRjGiaHCU7q8UH6Ap1V02ue4NTy7ymrTf34ZkNWXcCng7+4xN6+140rhWevfE87YRdo/Gf0Rmqg+0dFkNRSkaycNGefJoibqIvhQuxq/LpC0aoBiGf1+MIYeHrMf1SARIEffNV2cRkHYd9ulXvQEOnTVjhAoGBAOSxUzhogdbCBdpdG2cM0P0YZdkOdld0U5gHEVfwzp711cgUtMeVI2ojFfDB91N1ocueOwagq8+s5q7ygcBsi0FLIQQNJiThV7l9zGaZRrbn+4pjM2zd+eknlTx5j+RS8s3jqYXWqYUt1Yid03hJ890kbJYE2lVOqroI6XoqpRR9"
	kPrivateKey   = "MIIEpQIBAAKCAQEA1lXHtQsB6y8cATJH1UjQCAv7aq7DUrlkE3mdtQZcwOBn5PlaERxzazbwUk/Cxv7cX+YayE9l4vLkfV3GHWm3Rgk5OeT1OPPv2+t8d0hw+kmtOef+2hwZ+BMnXM58LXXVlj8GbsUbOtuZQj7OOJDyXiASkshZ6W5UKqDm9nPgW7ooIz0dH+A0vbUWWD8/t3xhWANnM2eHMI5yeaUosceLqKK5Y+gyFNxwnlWE+Ko0Sf68/ZUHrN67Q/cqHkU0z6Nw5xcpPPzrKTWQbUX2VV6IJ/vLJD7OUGKDIssejYMAKpPs0m4FAVgmLLgyw4PbMZCuefhJOZqZSyQH2t5MCk6n7wIDAQABAoIBAE2Me9VlRixxvxAvwQ3Kanp+21ieIs2rhioFtqnow2aFyxFtpsjKIniISCt/8FlPnSyVdNtE3vheKY2ygBvkRAtzCuGHlbIlkINhkIcYDsiAH8zzw6HmyP6Y74UEsKlCGSVjaFBrwI5rJehyEOsmhorHz/CLzPxIjutdjDNfea214xnlr4l5WYUWrvolGg03WvLEEbCgQQOmOo0m04IaHXZRl4uIyK62SPagflj9u+2oPho5Ezj0kTdL/qrtKNLdH1VxqKHmmYxGZZEvkVSbNFnGOvxu1tPDalu5KRO9SdNu018AquxE5Rw1KVl7KQDUXHmcPGbXkLRKk6Y6ltjRqAECgYEA/AtG7ilfOJbh2/vSkmaES8Fckg9D8SHzaODJc1D6bWdW5+YHbkxo3pxXs5bbteqs9hMuf4OESyEGOxnBF3luine8Vf+MlyUebVTQufept/r/KppqpIfLszKpy1g2/MtnNCXhbbHwRD6XvHjaIgHk9QLKQ7GWuLmPU7JPp5tsts8CgYEA2bL8pUxupGq1pUciLlPj9VmDMzvIiOL/Pu/ncpqx1H2XrI51Gj6dzwSnOMAqKkxF510x37fzuI8bMMG1/u8wjtQNHPYbC0L32fHhsGbmHrftjCBaAExHX1I1T503p/wZ/fdNQt+lMLAAnjWKQgoKwqSEJ1rjJeHIcJvLIfpdROECgYEArSiOPZdc3QMD/t9+ZqhZ4bXhhFNKiUKa+QXeQQR0WG9zzHRDzKpgLfhZZH+TSOMGmzTIcECJxhfVMQtblmYN5MGoOakNDNYqllB76hfVmRmu7rUR6SGGeAGpl5Nui7SunawcuQFToX8jPhAFRPHqO84D6gf7FcQeTREnGm50fQ8CgYEAy3BUYTS4ALYn4bhD3P9QfCuWS/6GPEXFOc9/fr3JiUWExCCslkYFuzwh+Qq7XKPCf5+7x9Fj1QkG491ickacHh1T08i5JSED9Yvw2KSQUAyZ1OU2tiiSWiW85BWLuVQCBi9g6CmPeZxAN5jZBzXTMGoFhbGNrAz+/xzYC3yoRIECgYEAw1N7Y09dBENNYVx1a0YHzzfEXulhQph9YCoC40ef+jIE6D10CpMMdPIQCmbB7+PB72HPiq8yltpeuvQCPa5div3VP2/I9ecyNMlJYDtPYfYtDBIFOm6P8hnM9mqXfw26cCEprMJBvOg51yPzA9jVHweBAFVTU7lrCqWb18CKhoA="
	kServerPort   = "9989"
	kServerDomain = "http://127.0.0.1" + ":" + kServerPort
)

func main() {
	var err error

	if aliClient, err = alipay.New(kAppId, kPrivateKey, false); err != nil {
		log.Println("初始化支付宝失败", err)
		return
	}

	// 使用支付宝证书
	if err = aliClient.LoadAppPublicCertFromFile("./ttt/appCertPublicKey_2016102000728006.crt"); err != nil {
		log.Println("加载证书发生错误", err)
		return
	}

	if err = aliClient.LoadAliPayRootCertFromFile("./ttt/alipayRootCert.crt"); err != nil {
		log.Println("加载证书发生错误", err)
		return
	}
	if err = aliClient.LoadAliPayPublicCertFromFile("./ttt/alipayCertPublicKey_RSA2.crt"); err != nil {
		log.Println("加载证书发生错误", err)
		return
	}

	var s = gin.Default()
	s.GET("/alipay", pay)
	s.GET("/callback", callback)
	s.POST("/notify", notify)
	s.Run(":" + kServerPort)
}

func pay(c *gin.Context) {
	var tradeNo = fmt.Sprintf("%d", xid.Next())

	var p = alipay.TradePagePay{}
	p.NotifyURL = "https://api.jinglan.art/api/vshopOrderDealNotice"
	p.ReturnURL = "https://api.jinglan.art/api/vshopOrderDealNotice"
	p.Subject = "test:" + tradeNo
	p.OutTradeNo = tradeNo
	p.TotalAmount = "10.00"
	p.ProductCode = "QUICK_WAP_PAY"

	url, _ := aliClient.TradePagePay(p)
	fmt.Println(url.String())
	c.Redirect(http.StatusTemporaryRedirect, url.String())
}

func callback(c *gin.Context) {
	c.Request.ParseForm()

	//ok, err := aliClient.VerifySign(c.Request.Form)
	//if err != nil {
	//	log.Println("回调验证签名发生错误", err)
	//	return
	//}
	//
	//if ok == false {
	//	log.Println("回调验证签名未通过")
	//	return
	//}

	var outTradeNo = c.Request.Form.Get("out_trade_no")
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo
	rsp, err := aliClient.TradeQuery(p)
	if err != nil {
		c.String(http.StatusBadRequest, "验证订单 %s 信息发生错误: %s", outTradeNo, err.Error())
		return
	}
	if rsp.IsSuccess() == false {
		c.String(http.StatusBadRequest, "验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Content.Msg, rsp.Content.SubMsg)
		return
	}

	c.String(http.StatusOK, "订单 %s 支付成功", outTradeNo)
}

func notify(c *gin.Context) {
	c.Request.ParseForm()

	ok, err := aliClient.VerifySign(c.Request.Form)
	if err != nil {
		log.Println("异步通知验证签名发生错误", err)
		return
	}

	if ok == false {
		log.Println("异步通知验证签名未通过")
		return
	}

	log.Println("异步通知验证签名通过")

	var outTradeNo = c.Request.Form.Get("out_trade_no")
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo
	rsp, err := aliClient.TradeQuery(p)
	if err != nil {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s \n", outTradeNo, err.Error())
		return
	}
	if rsp.IsSuccess() == false {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s-%s \n", outTradeNo, rsp.Content.Msg, rsp.Content.SubMsg)
		return
	}

	log.Printf("订单 %s 支付成功 \n", outTradeNo)
}
